﻿using System.CodeDom.Compiler;

namespace ShadowCode;
internal static class Extends
{
    public static string GetFileLineInfo(this FileLinePositionSpan span, string projectdir = "^")
    {
        return $"{span.Path.Replace(projectdir, "")} : {span.StartLinePosition.Line + 1} 行";
    }

    public static string GetFileLineInfo(this SyntaxNode node, string projectdir = "^") =>
        node.GetLocation().GetLineSpan().GetFileLineInfo(projectdir);

    public static ITypeSymbol UnNull(this ITypeSymbol type)
    {
        return type.WithNullableAnnotation(NullableAnnotation.NotAnnotated);
    }

    public static string JoinString<T>(this IEnumerable<T> values, string symbol = ", ") =>
    string.Join(symbol, values);


    /// <summary>
    /// 返回取消泛型参数的类型
    /// <![CDATA[ Class<T> 转换 Class<> ]]>
    /// </summary>
    /// <returns></returns>
    public static ITypeSymbol UnGenericParameterType(this ITypeSymbol type)
    {
        if (type is not INamedTypeSymbol namedType) return type;
        return namedType.UnGenericParameterType();
    }

    /// <summary>
    /// 返回取消泛型参数的类型
    /// <![CDATA[ Class<T> 转换 Class<> ]]>
    /// </summary>
    /// <returns></returns>
    public static INamedTypeSymbol UnGenericParameterType(this INamedTypeSymbol namedType)
    {
        if (!namedType.IsGenericType) return namedType;
        return namedType.ConstructUnboundGenericType();
    }

    /// <summary>
    /// 是否为泛型参数
    /// </summary>
    public static bool IsTypeParameter(this ITypeSymbol type)
    {
        return type is ITypeParameterSymbol || type.ContainingModule is null;
    }

    public static IndentedTextWriter WriteScope(this IndentedTextWriter textWriter,
        Action action)
    {
        textWriter.WriteLine('{');
        textWriter.Indent++;
        action();
        textWriter.Indent--;
        textWriter.WriteLine('}');
        return textWriter;
    }

    public static NotImplementedException CreateNotImplemented(this Type caller)
    {
        return new($"{caller.FullName} 未实现方法");
    }

    public static Dictionary<ITypeSymbol, int> GetGenericTypeIndex(this IEnumerable<ITypeSymbol> types)
    {
        var res = new Dictionary<ITypeSymbol, int>(SymbolEqualityComparer.Default);
        var index = 0;
        foreach (var item in types)
        {
            res[item] = index;
            index++;
        }
        return res;
    }

    public static bool EqualsDefault(this ISymbol source, ISymbol type)
    {
        return source.Equals(type, SymbolEqualityComparer.Default);
    }

    /// <summary>
    /// <![CDATA[
    /// 如果不包含泛型实参返回 MyClass<> 
    /// 否则返回 MyClass<string>
    /// ]]>
    /// </summary>
    public static ITypeSymbol TryUnGeneric(this ITypeSymbol type)
    {
        if (type is not INamedTypeSymbol namedType || !namedType.IsGenericType)
            return type;

        if (IsOriginalGenericType(namedType))
            return namedType.ConstructUnboundGenericType();

        return namedType;
    }

    /// <summary>
    /// 是否为原始泛型类
    /// </summary>
    public static bool IsOriginalGenericType(this INamedTypeSymbol type)
    {     
        return  type.TypeArguments.All(x => x.IsTypeParameter());
    }

    /// <summary>
    /// 是否为原始泛型类
    /// </summary>
    public static bool IsOriginalGenericType(this ITypeSymbol type)
    {
        if (type is not INamedTypeSymbol namedType) return false;
        return namedType.IsOriginalGenericType();
    }
       
}
